package com.bocai.service.impl;

import com.bocai.bean.*;
import com.bocai.mapper.*;
import com.bocai.service.IOrderService;
import com.bocai.utils.*;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service

public class OrderServiceImpl implements IOrderService {

    @Autowired
    private TUserInfoMapper userInfoMapper;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private SysUserInfoMapper sysUserInfoMapper;
    @Autowired
    private CashInfoMapper cashInfoMapper;
    @Autowired
    private RuleInfoMapper ruleInfoMapper;

    @Override
    public OrderInfo selectByOrderNumber(String orderNumber) {
        return orderInfoMapper.selectByOrderNumber(orderNumber);
    }

    @Override
    public ResponseData placeOrder(Integer userId,
                                   String accountId,
                                   Integer eventId,
                                   Integer marketId,
                                   Integer ruleTypeId,
                                   Integer selectionId,
                                   Double v1,
                                   Double v2,
                                   Double v3,
                                   String placedResult,
                                   BigDecimal requestPrice,
                                   BigDecimal requestAmount,
                                   String homeTeam,
                                   String awayTeam,
                                   String competitionName,
                                   ResponseData data) {

        CodeEnum codeEnum = ObjUtils.validateParams(new Object[]{eventId,
                marketId,
                ruleTypeId,
                selectionId,
                v1,v2,v3,
                placedResult,
                requestPrice,
                requestAmount,
                competitionName});

        String orderNumber = RandomUtils.getOrderNumber();

        RuleInfo ruleInfo = new RuleInfo();
        ruleInfo.setSelection(selectionId);
        ruleInfo.setRuleType(ruleTypeId);
        RuleInfo ruleInfo1 = this.ruleInfoMapper.selectByPrimaryKey(ruleInfo);

        Map<String,Object> result = new HashMap<>();
        result.put("correlationOrderId",orderNumber);
        result.put("accountId",accountId);
        result.put("eventId",eventId);
        result.put("marketId",marketId);
        result.put("selection",selectionId);
        result.put("v1",v1);
        result.put("v2",v2);
        result.put("v3",v3);
        result.put("placedResult",placedResult);
        result.put("requestPrice",requestPrice);
        result.put("requestAmount",requestAmount);
        result.put("selectionName",ruleInfo1.getSelectionName());
        result.put("ruleTypeName",ruleInfo1.getRuleTypeName());
        data.setResults(result);

        if (ObjUtils.isNotEmpty(codeEnum)){
            data.setCodeEnum(CodeEnum.CODE_90001);
            return data;
        }

        TUserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);

        if (null == userInfo) {
            //用户不存在
            data.setCodeEnum(CodeEnum.CODE_10003);
            return data;
        }

        if (userInfo.getUserStatus() != 1){
            data.setCodeEnum(CodeEnum.CODE_90005);
            return data;
        }

        Map<String, Object> map = new HashMap<>();
        map.put("correlationOrderId",orderNumber);
        map.put("accountId",accountId);
        map.put("eventId",eventId);
        map.put("marketId",marketId);
        map.put("selection",selectionId);
        map.put("v1",v1);
        map.put("v2",v2);
        map.put("v3",v3);
        map.put("placedResult",placedResult);
        map.put("requestPrice",requestPrice);
        map.put("requestAmount",requestAmount.divide(new BigDecimal(16)));  //汇率换算1:16

        TCMObject tcmObject = GetResultUtils.getObject(SysConstant.ORDER_PLACE,map);
        if (tcmObject.getStatus().equals(200)){

            String tcmOrderId = tcmObject.getBody().getJSONObject("data").getJSONObject("order").getString("orderId");

            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setOrderNumber(orderNumber);
            orderInfo.setUserId(userId);
            orderInfo.setOrderMoney(requestAmount);
            orderInfo.setCreateTime(new Date());
            orderInfo.setOrderOdds(requestPrice);
            orderInfo.setTcmOrderId(tcmOrderId);
            orderInfo.setRuleTypeId(ruleTypeId);
            orderInfo.setSelectionId(selectionId);
            orderInfo.setEventId(eventId);
            orderInfo.setMarketId(marketId);
            orderInfo.setOrderState(0);
            orderInfo.setHomeTeam(homeTeam);
            orderInfo.setAwayTeam(awayTeam);
            orderInfo.setCompetitionName(competitionName);

            //主账户
            BigDecimal money = userInfo.getUserAccount();
            //奖励账户
            BigDecimal reward = userInfo.getUserMoneyReward();
            //需要花费
            BigDecimal cost = orderInfo.getOrderMoney();

            if ((money.add(reward)).compareTo(cost) < 0) {
                //余额不足
                data.setCodeEnum(CodeEnum.CODE_10009);
                return data;
            }

            if (reward.compareTo(cost) >= 0) {
                userInfo.setUserMoneyReward(cost);
                userInfo.setUserAccount(null);
                orderInfo.setOrderFictitiousMoney(cost);
            } else {
                userInfo.setUserAccount(cost.subtract(reward));
                userInfo.setUserMoneyReward(reward);
                orderInfo.setOrderFictitiousMoney(reward);
            }

            //修改钱包余额
            if (userInfoMapper.updateCashUserMoney(userInfo) <= 0) {
                //修改钱包失败
                data.setCodeEnum(CodeEnum.CODE_1);
                return data;
            }

            if (orderInfoMapper.insertSelective(orderInfo) <= 0) {
                //插入订单表失败
                data.setCodeEnum(CodeEnum.CODE_1);
                return data;
            }

        }else {
            data.setCodeEnum(CodeEnum.CODE_60001);
        }

        return data;
    }


    @Override
    public int updateOrderStatus(JSONObject jsonObject) {

        String orderNumber = jsonObject.getString("correlationOrderId");
        Integer status = jsonObject.getInt("status");

        double netPnL = jsonObject.getDouble("netPnL");

        OrderInfo orderInfo = orderInfoMapper.selectByOrderNumber(orderNumber);

        //修改status
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", status);
        map.put("orderNumber", orderNumber);
        if (netPnL > 0){
            map.put("isWin",1);
        }else {
            map.put("isWin",0);
        }

        orderInfoMapper.updateStatusByOrderNumber(map);

        //修改钱包

        TUserInfo userInfo = new TUserInfo();
        userInfo.setUserId(orderInfo.getUserId());

        if (orderInfo.getOrderState() != status) {
            if (status.equals(OrderStatus.Pending.getValue())) {
                // 等待处理，基本不会走这个
            } else if (status.equals(OrderStatus.Active.getValue())) {
                // 订单正常
            } else if (status.equals(OrderStatus.Settled.getValue())) {
                // 订单已结算，结算金钱
                //如果赢了，获得金额
                if (netPnL > 0){
                    BigDecimal money = orderInfo.getOrderMoney().multiply(orderInfo.getOrderOdds());
                    userInfo.setUserAccount(money);
                    userInfoMapper.updateAddCashUserMoney(userInfo);
                }else {
                    //输了
                }

            } else {
                //订单取消等状态，退回金额,优惠券不退回
                BigDecimal money = orderInfo.getOrderMoney().subtract(orderInfo.getOrderFictitiousMoney());

                userInfo.setUserAccount(money);
                userInfoMapper.updateAddCashUserMoney(userInfo);
            }
        }

        return 1;
    }

    @Override
    public ResponseData selectOrderCount(OrderInfo orderInfo, ResponseData data) {
        CodeEnum codeEnum = ObjUtils.validateParams(new Object[]{orderInfo.getEventId(),orderInfo.getRuleTypeId()});
        if (ObjUtils.isNotEmpty(codeEnum)){
            data.setCodeEnum(CodeEnum.CODE_90002);
            return data;
        }

        data.setResults(orderInfoMapper.selectOrderCount(orderInfo));
        data.setCodeEnum(CodeEnum.SUCCESS);

        return data;
    }

    @Override
    public ResponseData selectOrderCountDetail(OrderInfo orderInfo, ResponseData data) {
        CodeEnum codeEnum = ObjUtils.validateParams(new Object[]{orderInfo.getEventId(),
                orderInfo.getRuleTypeId(),
        orderInfo.getSelectionId()});
        if (ObjUtils.isNotEmpty(codeEnum)){
            data.setCodeEnum(CodeEnum.CODE_90002);
            return data;
        }

        data.setResults(orderInfoMapper.selectOrderCountDetail(orderInfo));
        data.setCodeEnum(CodeEnum.SUCCESS);
        return data;
    }

    @Override
    public ResponseData selectByUserId(Integer userId,Integer status,ResponseData data) {
        CodeEnum codeEnum = ObjUtils.validateParams(new Object[]{userId});
        if (ObjUtils.isNotEmpty(codeEnum)) {
            data.setCodeEnum(CodeEnum.CODE_90001);
            return data;
        }

        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        map.put("state",status);

        data.setResults(orderInfoMapper.selectByUserId(map));
        return data;
    }

    @Override
    public ResponseData selectOrderManager(Map<String, Object> map, ResponseData data) {
        data.setResults(orderInfoMapper.selectOrderManager(map));
        return data;
    }

    @Override
    public List<OrderInfo> selectByMarketId(OrderInfo orderInfo) {
        return orderInfoMapper.selectByMarketId(orderInfo);
    }

    @Override
    public ResponseData selectAllMoneyNum(Integer userId, ResponseData data) {
        if (null == userId || userId <= 0) {
            data.setCodeEnum(CodeEnum.CODE_90002);
        } else {
            SysUserInfo sysUserInfo = sysUserInfoMapper.selectByPrimaryKey(userId);
            if (null == sysUserInfo) {
                data.setCodeEnum(CodeEnum.CODE_90003);
            } else {
                HashMap<String, BigDecimal> map = new HashMap<>();
                if (null == cashInfoMapper.selectMoneyNum()){
                    map.put("cashMoney", new BigDecimal(0));
                }else{
                    map.put("cashMoney", cashInfoMapper.selectMoneyNum());
                }
                if (null == orderInfoMapper.selectMoneyNum()){
                    map.put("rewardMoney", new BigDecimal(0));
                }else{
                    map.put("rewardMoney", orderInfoMapper.selectMoneyNum());
                }
                data.setResults(map);
            }
        }
        return data;
    }
}
